package com.quanqiutong.hprt_tscl;

import androidx.annotation.NonNull;

import io.flutter.embedding.engine.plugins.FlutterPlugin;
import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;
import io.flutter.plugin.common.MethodChannel.MethodCallHandler;
import io.flutter.plugin.common.MethodChannel.Result;

import android.content.Context;
import android.content.res.AssetManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.widget.Toast;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;

import java.io.InputStream;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.HashMap;
import java.util.Set;

import tspl.HPRTPrinterHelper;
import com.quanqiutong.hprt_tscl.utils.BitmapUtil;

/** HprtTsclPlugin */
public class HprtTsclPlugin implements FlutterPlugin, MethodCallHandler {
  /// The MethodChannel that will the communication between Flutter and native
  /// Android
  ///
  /// This local reference serves to register the plugin with the Flutter Engine
  /// and unregister it
  /// when the Flutter Engine is detached from the Activity
  private MethodChannel channel;
  private Context context;

  @Override
  public void onAttachedToEngine(@NonNull FlutterPluginBinding flutterPluginBinding) {
    System.out.println("onAttachedToEngine");
    this.context = flutterPluginBinding.getApplicationContext();
    channel = new MethodChannel(flutterPluginBinding.getBinaryMessenger(), "hprt_tscl");
    channel.setMethodCallHandler(this);
  }

  private Map<String, String> getBLEDevices() {
    Map<String, String> map = new HashMap<String, String>();
    BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
    if (bluetoothAdapter == null) {
      // 设备不支持蓝牙
      return map;
    }
    if (!bluetoothAdapter.isEnabled()) {
      // 蓝牙未开启
      return map;
    }
    Set<BluetoothDevice> bondedDevices = bluetoothAdapter.getBondedDevices();
    for (BluetoothDevice device : bondedDevices) {
      if (device.getBondState() == BluetoothDevice.BOND_BONDED) {
        String deviceName = device.getName();
        String deviceAddress = device.getAddress();
        map.put(deviceAddress, deviceName);
      }
    }
    return map;
  }

  @Override
  public void onMethodCall(@NonNull MethodCall call, @NonNull Result result) {
    try {
      int res = 1;
      Map arg = call.arguments();
      System.out.println(call.method);
      System.out.println(arg);
      if (call.method.equals("portOpen")) {
        res = HPRTPrinterHelper.PortOpen("Bluetooth," + (String) arg.get("portSetting"));
      } else if (call.method.equals("portClose")) {
        HPRTPrinterHelper.PortClose();
        res = 1;
      } else if (call.method.equals("isOpened")) {
        boolean isOpened = HPRTPrinterHelper.IsOpened();
        res = isOpened ? 1 : 0;
      } else if (call.method.equals("devices")) {
        Map<String, String> map = getBLEDevices();
        result.success(map);
        return;
      } else if (call.method.equals("selfTest")) {
        HPRTPrinterHelper.SelfTest();
        res = 1;
      } else if (call.method.equals("printAreaSize")) {
        res = HPRTPrinterHelper.printAreaSize((String) arg.get("width"), (String) arg.get("height"));
      } else if (call.method.equals("print")) {
        res = HPRTPrinterHelper.Print((String) arg.get("strnum"), (String) arg.get("strcopies"));
      } else if (call.method.equals("gap")) {
        res = HPRTPrinterHelper.Gap((String) arg.get("distance"), (String) arg.get("offset"));
      } else if (call.method.equals("offset")) {
        res = HPRTPrinterHelper.Offset((String) arg.get("distance"));
      } else if (call.method.equals("cls")) {
        HPRTPrinterHelper.CLS();
        res = 1;
      } else if (call.method.equals("printText")) {
        String xpos = (String) arg.get("xpos");
        String ypos = (String) arg.get("ypos");
        String font = (String) arg.get("font");
        String rotation = (String) arg.get("rotation");
        String xmultiplication = (String) arg.get("xmultiplication");
        String ymultiplication = (String) arg.get("ymultiplication");
        String codedata = (String) arg.get("codedata");

        res = HPRTPrinterHelper.WriteData(("TEXT " + xpos + "," + ypos + ",\"" + font + "\"," + rotation + ","
            + xmultiplication + "," + ymultiplication + ",\"" + codedata + "\"\r\n").getBytes("GB2312"));
      } else if (call.method.equals("printText1")) {
        res = HPRTPrinterHelper.printText((String) arg.get("xpos"), (String) arg.get("ypos"),
            (String) arg.get("font"), (String) arg.get("rotation"),
            (String) arg.get("xmultiplication"), (String) arg.get("ymultiplication"),
            (int) arg.get("alignment"), (String) arg.get("codedata"));
      } else if (call.method.equals("printText2")) {
        res = HPRTPrinterHelper.printText((String) arg.get("xpos"), (String) arg.get("ypos"),
            (String) arg.get("font"), (String) arg.get("rotation"),
            (int) arg.get("size"), (int) arg.get("alignment"), (String) arg.get("codedata"));
      } else if (call.method.equals("direction")) {
        res = HPRTPrinterHelper.Direction((String) arg.get("direction"));
      } else if (call.method.equals("reference")) {
        res = HPRTPrinterHelper.Reference((String) arg.get("xpos"), (String) arg.get("ypos"));
      } else if (call.method.equals("codepage")) {
        res = HPRTPrinterHelper.Codepage((String) arg.get("codepage"));
      } else if (call.method.equals("printBarcode")) {
        res = HPRTPrinterHelper.printBarcode((String) arg.get("xpos"), (String) arg.get("ypos"),
            (String) arg.get("codetype"), (String) arg.get("height"), (String) arg.get("readable"),
            (String) arg.get("rotation"), (String) arg.get("narrow"), (String) arg.get("wide"),
            (String) arg.get("codedata"));
      } else if (call.method.equals("printQRcode")) {
        res = HPRTPrinterHelper.printQRcode((String) arg.get("xpos"), (String) arg.get("ypos"),
            (String) arg.get("ecclevel"), (String) arg.get("width"), (String) arg.get("mode"),
            (String) arg.get("rotation"), (String) arg.get("codedata"));
      } else if (call.method.equals("feed")) {
        res = HPRTPrinterHelper.Feed((String) arg.get("len"));
      } else if (call.method.equals("formfeed")) {
        res = HPRTPrinterHelper.Formfeed();
      } else if (call.method.equals("bar")) {
        res = HPRTPrinterHelper.Bar((String) arg.get("xpos"), (String) arg.get("ypos"),
            (String) arg.get("width"), (String) arg.get("height"));
      } else if (call.method.equals("home")) {
        res = HPRTPrinterHelper.Home();
      } else if (call.method.equals("printImage")) {
        byte[] b = (byte[]) arg.get("bytes");
        Bitmap bmp = null;
        if (b.length != 0) {
          bmp = BitmapFactory.decodeByteArray(b, 0, b.length);
        }
        res = HPRTPrinterHelper.printImage((String) arg.get("xpos"), (String) arg.get("ypos"), bmp,
            (boolean) arg.get("isNegate"), (boolean) arg.get("isLZO"), (int) arg.get("type"));
      } else if (call.method.equals("density")) {
        res = HPRTPrinterHelper.Density((String) arg.get("contrast"));
      } else if (call.method.equals("speed")) {
        res = HPRTPrinterHelper.Speed((String) arg.get("speed"));
      } else if (call.method.equals("cut")) {
        res = HPRTPrinterHelper.Cut();
      } else if (call.method.equals("box")) {
        res = HPRTPrinterHelper.Box((String) arg.get("xstart"), (String) arg.get("ystart"),
            (String) arg.get("xend"), (String) arg.get("yend"),
            (String) arg.get("thickness"));
      } else if (call.method.equals("sound")) {
        res = HPRTPrinterHelper.Sound((String) arg.get("level"), (String) arg.get("interval"));
      } else if (call.method.equals("writeData")) {
        res = HPRTPrinterHelper.WriteData((byte[]) arg.get("bData"));
      } else if (call.method.equals("reverse")) {
        res = HPRTPrinterHelper.Reverse((String) arg.get("xstart"), (String) arg.get("ystart"),
            (String) arg.get("xwidth"), (String) arg.get("yheight"));
      } else if (call.method.equals("bold")) {
        res = HPRTPrinterHelper.Bold((int) arg.get("bold"));
      } else if (call.method.equals("getPrinterStatus")) {
        res = HPRTPrinterHelper.getPrinterStatus();
      } else if (call.method.equals("printBlock")) {
        res = HPRTPrinterHelper.printBlock((int) arg.get("startX"), (int) arg.get("startY"),
            (int) arg.get("width"), (int) arg.get("height"), (int) arg.get("font"),
            (int) arg.get("rotation"), (int) arg.get("multiplicationX"), (int) arg.get("multiplicationY"),
            (int) arg.get("space"), (int) arg.get("alignment"), (String) arg.get("content"));
      } else if (call.method.equals("printQRCodeImage")) {
        Bitmap bitmap = BitmapUtil.generateBitmap((String) arg.get("data"), 9,
            (int) arg.get("width"), (int) arg.get("height"));

        res = HPRTPrinterHelper.printImage((String) arg.get("xpos"), (String) arg.get("ypos"), bitmap,
            (boolean) arg.get("isNegate"), (boolean) arg.get("isLZO"), (int) arg.get("type"));
      } else {
        result.notImplemented();
      }
      result.success(res);
    } catch (Exception e) {
      System.out.println(e.getMessage());
      result.error("0", e.getMessage(), "");
    }
  }

  @Override
  public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) {
    channel.setMethodCallHandler(null);
  }
}
